-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a function to save a slice in MDH format #149
Conversation
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## master #149 +/- ##
==========================================
+ Coverage 38.67% 38.90% +0.22%
==========================================
Files 239 240 +1
Lines 15829 15971 +142
==========================================
+ Hits 6122 6213 +91
- Misses 9707 9758 +51
☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code looks ok. But there are a couple of issues:
- I get an error when the output file already exists - could you either document this or automatically remove / overwrite the file? (I think this might be a Matlab HDF issue). Maybe do a
if exist(filename, 'file'), delete(filename);
? - Could you move the
read_struct
function into thesw_spec2MDHisto.m
file (I don't think it's used anywhere else and I would rather it not be in the root folder as a separate m-file). - Could you add an example to the doc-text / help? It's a bit confusing at the moment. In particular, I would change the text to be something like:
% spectra: a structure calculated by sw_egrid
% Only a single q-direction can be given in the call to spinwave
% proj: a 3x3 matrix where each column is a vector defining the orientation of the view.
% One of the vectors must be along the q-axis used in the spinwave call
% dproj: is a 3 vector that is the bin size in each direction
% filename: is the name of the nexus file.
%
% Example:
% q0 = [0 0 0];
% qdir = [1 0 0];
% spec = sw_egrid(spinwave(sw_model('triAF', 1), {q0 q0+qdir 100}))
% proj = [qdir(:) [0 1 0]' [0 0 1]'];
% dproj = [0.05, 0.05, 0.05];
% sw_spec2MDHisto(sp, proj, dproj, 'testmdh.nxs');
%
% Note that:
% (1) In the call to `spinwave`, only one q-direction may be specified
% e.g. the HKL specifier must be of the form {q0 q0+qdir nsteps}
% (2) one column in the `proj` matrix must be the q-direction used in
% `spinwave` (e.g. `qdir`).
Otherwise I tested with the following code:
swo = sw_model('triAF', 1);
sp = sw_egrid(sw_neutron(spinwave(swo, {[0 0 0] [1 0 0] 100})),'component','Sperp', 'Evect', linspace(0,5,200));
sw_spec2MDHisto(sp, [1 0 0; 0 1 0; 0 0 1], [0.01, 0.01, 0.01], 'testmdh.nxs');
And I could read the resulting testmdh.nxs
file in Mantid 6.6, where it gives a 2D spectra along the Qh direction and the MDH files says that it's integrated between -0.005 and +0.005 along the Qk and Ql directions (which bin size is given by the dproj
input I guess?).
However, when I use:
sp = sw_egrid(sw_neutron(spinwave(swo, {[0 0 0] [1 0 0] [0 1 0] 100})),'component','Sperp', 'Evect', linspace(0,5,200));
sw_spec2MDHisto(sp, [1 0 0; 0 1 0; 0 0 1], [0.01, 0.01, 0.01], 'testmdh.nxs');
It gives the wrong spectrum - it plots the whole thing as if it was only along Qk.
And when I use:
sp = sw_egrid(sw_neutron(spinwave(swo, {[0 0 0] [1 1 1] 100})),'component','Sperp', 'Evect', linspace(0,5,200));
sw_spec2MDHisto(sp, [1 0 0; 0 1 0; 0 0 1], [0.01, 0.01, 0.01], 'testmdh.nxs');
It gives an error, as does:
sp = sw_egrid(sw_neutron(spinwave(swo, {[0 0 0] [1 1 1] 100})),'component','Sperp', 'Evect', linspace(0,5,200));
sw_spec2MDHisto(sp, [1 0 0; 1 1 0; 1 0 1], [0.01, 0.01, 0.01], 'testmdh.nxs');
So - does proj
have to be a set of orthogonal axes?
In future is it possible to automatically calculate proj
from the spectrum structure? (Maybe if the user gives one other q-direction / defines a scattering plane).
@mducle All Good points. I will update accordingly. |
@mducle I think I have changed things to match the requested changed. Let me know if anything else is needed. |
Thanks for this @granrothge!
it produces this workspace in mantid
produces this error
|
I was wondering does the proj matrix need to have the normalised unit vectors? Or maybe I'm mis-interpreting it...?
I get the same error as above.
I don't get the error, but the algorithm seems to hang and the .nxs file is not closed (so can't be opened in mantid). |
@RichardWaiteSTFC @mducle OK Let me do some more rigorous testing. As to question 1. I Do not envision doing more than one direction at a time. I will at least add some documentation and may add an error catch. |
@mducle @RichardWaiteSTFC I think I have addressed the off axis case. Good catch. I also added a prototype of a test script that provides which directions should be tested. I'm not familiar with the testing setup so it will likely need to be modified to actually run. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unit test has a few bugs - but thanks for writing them!
function test_1_0_0(testCase) | ||
q0 = [0 0 0]; | ||
qdir = [1 0 0]; | ||
spec = sw_egrid(spinwave(sw_model('triAF', 1), {q0 q0+qdir nsteps})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The spinw model appears to be the same used for all tests. You can add this to a TestClassSetup
or TestMethodSetup
like so
spinw/+sw_tests/+unit_tests/unittest_spinw_optmagk.m
Lines 16 to 29 in 49880bc
methods (TestClassSetup) | |
function set_seed(testCase) | |
testCase.orig_rng_state = rng; | |
rng('default'); | |
end | |
end | |
methods (TestMethodSetup) | |
function setup_chain_model(testCase) | |
testCase.swobj = spinw(); | |
testCase.swobj.genlattice('lat_const', [3 8 8]) | |
testCase.swobj.addatom('r',[0; 0; 0],'S',1) | |
testCase.swobj.gencoupling(); | |
end | |
end |
In this case
TestClassSetup
is probably best as it isn't changed in any of the tests.
% `spinwave` (e.g. `qdir`). | ||
|
||
|
||
if nargin==0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We typically add a unit test for this like so
spinw/+sw_tests/+unit_tests/unittest_spinw_addatom.m
Lines 33 to 40 in 49880bc
function test_no_input_calls_help(testCase) | |
% Tests that if call addmatrix with no input, it calls the help | |
help_function = sw_tests.utilities.mock_function('swhelp'); | |
testCase.swobj.addatom(); | |
testCase.assertEqual(help_function.n_calls, 1); | |
testCase.assertEqual(help_function.arguments, ... | |
{{'spinw.addatom'}}); | |
end |
dproj = [norm((qdir-q0))/nsteps, 1e-6, 1e-6]; | ||
sw_spec2MDHisto(spec, proj, dproj, 'tmp/test112mdh.nxs'); | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there should be another end
here.
function test_1_0_0(testCase) | ||
q0 = [0 0 0]; | ||
qdir = [1 0 0]; | ||
spec = sw_egrid(spinwave(sw_model('triAF', 1), {q0 q0+qdir nsteps})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More importantly when I add the missing end
and run the tests they fail because nsteps
isn't defined!
Ah having looked at the doc string I think I needed to update the
but I got the same result - I would expect the end x value to be sqrt(2) |
I thought I had fixed the issue with the negative axis. I will look into it as well as the normalization issues. |
Aah here is the problem with the projection. It must be in columns not rows.
not
|
Sorry, it does say that in the doc string but I missed it! Thanks for clearing that up! |
@RichardWaiteSTFC @mducle Ok So I think this is now as ready as I can get it.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Garrett, could you change the test file to this:
classdef unittest_spinw_spec2MDHisto < sw_tests.unit_tests.unittest_super
properties
swModel = [];
tmpdir = '';
testfilename = '';
nsteps = {100};
end
properties (TestParameter)
testpars = struct(...
'test_1_0_0', struct('q0', [0 0 0], 'qdir', [1 0 0], 'proj', [[1 0 0]' [0 1 0]' [0 0 1]'], 'nxs', 'test100mdh.nxs'), ...
'test_1_1_0', struct('q0', [0 0 0], 'qdir', [1 1 0], 'proj', [[1 1 0]' [1 -1 0]' [0 0 1]'], 'nxs', 'test110mdh.nxs'), ...
'test_1_1_1', struct('q0', [0 0 0], 'qdir', [1 1 1], 'proj', [[1 1 1]' [1 -1 0]' [1 1 -2]'], 'nxs', 'test111mdh.nxs'), ...
'test_1_1_2', struct('q0', [0 0 2], 'qdir', [1 1 0], 'proj', [[1 1 0]' [1 -1 0]' [0 0 1]'], 'nxs', 'test112mdh.nxs'), ...
'test_1_1_2_2', struct('q0', [0 0 2], 'qdir', [1 1 0], 'proj', [[1 -1 0]' [1 1 0]' [0 0 1]'], 'nxs', 'test112_2mdh.nxs'), ...
'test_2_2_2', struct('q0', [2 2 2], 'qdir', [1 1 0], 'proj', [[1 1 0]' [1 -1 0]' [0 0 1]'], 'nxs', 'test222mdh.nxs'));
end
methods (TestClassSetup)
function setup_model(testCase)
testCase.swModel = sw_model('triAF', 1);
end
function setup_tempdir(testCase)
testCase.tmpdir = tempdir;
end
end
methods (TestMethodTeardown)
function remove_tmpdir(testCase)
delete(testCase.testfilename);
end
end
methods (Test)
function test_qdirs(testCase, testpars)
q0 = testpars.q0;
qdir = testpars.qdir;
proj = testpars.proj;
testCase.disable_warnings('spinw:spinwave:NonPosDefHamiltonian');
spec = sw_egrid(spinwave(testCase.swModel, {q0 q0+qdir testCase.nsteps{1}}));
dproj = [norm((qdir-q0))/testCase.nsteps{1}, 1e-6, 1e-6];
testCase.testfilename = fullfile(testCase.tmpdir, testpars.nxs);
sw_spec2MDHisto(spec, proj, dproj, testCase.testfilename);
end
function test_non_ortho(testCase)
q0 = [0 0 2];
qdir = [1 1 0];
spec = sw_egrid(spinwave(testCase.swModel, {q0 q0+qdir testCase.nsteps{1}}));
proj = [qdir(:) [1 0 0]' [0 0 1]'];
dproj = [1e-6, norm((qdir-q0))/testCase.nsteps{1}, 1e-6];
verifyError(testCase,@() sw_spec2MDHisto(spec, proj, dproj, 'tmp/test_blank.nxs'), "read_struct:nonorthogonal")
end
end
end
To make it more compact and fix the filename issue.
Otherwise it looks fine to me.
@RichardWaiteSTFC I think it is ready to approve and go. |
This function will take the output of a spectra and create a slice in an MDH format.
Note the "Instrument" name is hard coded as a valid instrument is needed for Mantid to read the file. I'd prefer this to be "SpinW", but since that is not a valid Mantid instrument it can't be read by Mantid. I would like to see this requirement relaxed in Mantid, but that is a different discussion.